﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Data.SQLite;
namespace Knowledge
{
    public partial class MainForm : Form
    {
        private string _ApplicationPath;
        private string _DBPath;
        private string _ConnectionString;
        private string CategoriesSql = @"select * from [DocumentCategories] order by [Index]";
        public const string DocumentAndCategorieGuidSqlString = @"select * from [Document_DocumentCategories]";
        private const string DocumentListSqlString = @"select [Guid],[Title],[KeyWords] from [DocumentInfo] ";
        private string IndexSql = "";
        private string DocumentSql = "select [content] from [documentinfo] where [Guid]=@Guid";
        private string DocumentInfoByCategorieSqlString = @"select [Guid],[Title],[KeyWords],[Url] from [DocumentInfo] where [Guid] in (Select [DocumentGuid] from [Document_DocumentCategories] where [DocumentCategoriesGuid]=@DocumentCategoriesGuid)";
        private string DocumentCategorieSqlString = @"select * from [DocumentCategories] order by [Index]";
        private List<Document_DocumentCategories> DocumentAndCategorieList;
        private List<DocumentInfo> DocumentList;
        private DocumentCategorieTree DocumentCategoriesTree;

        public MainForm()
        {
            InitializeComponent();
            _ApplicationPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase) + "\\";
            _DBPath = _ApplicationPath + "document.db";
            openDBDialog.InitialDirectory = _ApplicationPath;
            _ConnectionString = "Data Source=" + _DBPath;
            DocumentAndCategorieList = new List<Document_DocumentCategories>();
            DocumentList = new List<DocumentInfo>();
            DocumentCategoriesTree = new DocumentCategorieTree();
            Init();
        }

        private void Init()
        {
            LoadDocumentList();
            LoadDocumentAndCategorieList();
            LoadDocumentCategoriesTree();
            InitTree();
        }

        #region loadData

        private void LoadDocumentList()
        {
            DocumentList.Clear();
            try
            {
                string connectionString = _ConnectionString;
                string SqlString = DocumentListSqlString;
                using (SQLiteConnection connection = new SQLiteConnection(connectionString))
                {
                    connection.Open();
                    using (SQLiteCommand command = connection.CreateCommand())
                    {
                        command.CommandText = SqlString;
                        try
                        {
                            SQLiteDataReader reader = command.ExecuteReader();
                            while (reader.Read())
                            {
                                DocumentInfo info = new DocumentInfo();
                                info.Guid = reader["Guid"].ToString();
                                info.Title = reader["Title"].ToString();
                                info.KeyWords = reader["KeyWords"].ToString();
                                DocumentList.Add(info);
                            }
                        }
                        catch (SQLiteException ex) { MessageBox.Show(ex.Message); }
                    }
                }
            }
            catch (SQLiteException ex) { MessageBox.Show(ex.Message); }
        }

        private void LoadDocumentAndCategorieList()
        {
            DocumentAndCategorieList.Clear();
            try
            {
                string connectionString = _ConnectionString;
                string SqlString = DocumentAndCategorieGuidSqlString;
                using (SQLiteConnection connection = new SQLiteConnection(connectionString))
                {
                    connection.Open();
                    using (SQLiteCommand command = connection.CreateCommand())
                    {
                        command.CommandText = SqlString;
                        try
                        {
                            SQLiteDataReader reader = command.ExecuteReader();
                            while (reader.Read())
                            {
                                Document_DocumentCategories document_DocumentCategories = new Document_DocumentCategories();
                                document_DocumentCategories.CategorieGuid = reader["DocumentCategoriesGuid"].ToString();
                                document_DocumentCategories.DocumentGuid = reader["DocumentGuid"].ToString();
                                foreach (DocumentInfo info in DocumentList)
                                {
                                    if (info.Guid==document_DocumentCategories.DocumentGuid)
                                    {
                                        document_DocumentCategories.Document = info;
                                        break;
                                    }

                                }
                                DocumentAndCategorieList.Add(document_DocumentCategories);
                            }
                        }
                        catch (SQLiteException ex) { MessageBox.Show(ex.Message+ex.InnerException.ToString()); }
                    }
                }
            }
            catch (SQLiteException ex) { MessageBox.Show(ex.Message); }
        }

        private void LoadDocumentCategoriesTree()
        {
            DocumentCategoriesTree.Categories.Clear();
            try
            {
                string connectionString = _ConnectionString;
                string addSqlString = DocumentCategorieSqlString;
                using (SQLiteConnection connection = new SQLiteConnection(connectionString))
                {
                    connection.Open();
                    using (SQLiteCommand command = connection.CreateCommand())
                    {
                        command.CommandText = addSqlString;

                        try
                        {
                            SQLiteDataReader reader = command.ExecuteReader();
                            while (reader.Read())
                            {
                                DocumentCategorie categorie = new DocumentCategorie();
                                categorie.Guid = reader["Guid"].ToString();
                                categorie.Index = int.Parse(reader["Index"].ToString());
                                categorie.Name = reader["Name"].ToString();
                                categorie.ParentGuid = reader["ParentGuid"].ToString();
                                categorie.Text = reader["Text"].ToString();
                                categorie.RootGuid = reader["RootGuid"].ToString();

                                DocumentCategoriesTree.Add(categorie);
                            }
                        }
                        catch (SQLiteException ex) { MessageBox.Show(ex.Message); }
                    }
                }
            }
            catch (SQLiteException ex) { MessageBox.Show(ex.Message); }
        }

        #endregion

        #region initTree
        private void InitTree()
        {
            Categories_Tree.Nodes.Clear();
            foreach (DocumentCategorie ca in DocumentCategoriesTree.Root)
            {
                TreeNode node = new TreeNode();
                node.Text = ca.Text;
                node.Tag = ca;
                node.ImageIndex = 0;
                node.Checked = false;
                Categories_Tree.Nodes.Add(node);
                try
                {
                    foreach (Document_DocumentCategories dcategorie in DocumentAndCategorieList)
                    {
                        if (dcategorie.CategorieGuid == ca.Guid && dcategorie.Document != null)
                        {
                            TreeNode infonode = new TreeNode();
                            infonode.Text = dcategorie.Document.Title;
                            infonode.Tag = dcategorie.Document;
                            infonode.ImageIndex = 2;
                            infonode.SelectedImageIndex = 2;
                            node.Nodes.Add(infonode);
                        }
                    }
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
                foreach (DocumentCategorie cason in ca.Sons)
                {
                    AddTreeNode(cason, node);

                }
            }

        }

        private void AddTreeNode(DocumentCategorie ca, TreeNode parentnode)
        {
            TreeNode node = new TreeNode();
            node.Text = ca.Text;
            node.Tag = ca;
            parentnode.Nodes.Add(node);
            foreach (Document_DocumentCategories dcategorie in DocumentAndCategorieList)
            {
                if (dcategorie.CategorieGuid == ca.Guid && dcategorie.Document != null)
                {
                    TreeNode infonode = new TreeNode();
                    infonode.Text =dcategorie.Document.Title;
                    infonode.Tag = dcategorie.Document;
                    infonode.ImageIndex = 2;
                    infonode.SelectedImageIndex = 2;
                    node.Nodes.Add(infonode);
                }
            }
            foreach (DocumentCategorie cason in ca.Sons)
            {
                AddTreeNode(cason, node);
            }
        }

        #endregion
        private void Exit_Menu_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void Categories_Tree_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (e.Node.Tag.GetType() == typeof(DocumentInfo))
            {
                DocumentInfo info = e.Node.Tag as DocumentInfo;
                string html = DocumentContent(info.Guid);
                MainTabControl.SelectedIndex = 1;
                wb.DocumentText = html;
            }

        }

        private string DocumentContent(string documentguid)
        {
            string connectionString = _ConnectionString;
            string addSqlString = DocumentSql;
            string result = string.Empty;
            using (SQLiteConnection connection = new SQLiteConnection(connectionString))
            {
                connection.Open();
                using (SQLiteCommand command = connection.CreateCommand())
                {
                    command.CommandText = addSqlString;
                    SQLiteParameter param = command.CreateParameter();
                    param.DbType = DbType.String;
                    param.Value = documentguid;
                    param.ParameterName = "@Guid";
                    command.Parameters.Add(param);
                    result = command.ExecuteScalar().ToString();

                }
            }
            return result;

        }

        bool isdrag = false;
        Point position;

        private void MainForm_MouseDown(object sender, MouseEventArgs e)
        {
            isdrag = true;
            position = new Point(e.X, e.Y);

        }

        private void MainForm_MouseUp(object sender, MouseEventArgs e)
        {
            position = new Point(e.X, e.Y);
            isdrag = false;
        }

        private void OpenDB_Menu_Click(object sender, EventArgs e)
        {
            if (openDBDialog.ShowDialog() == DialogResult.OK)
            {
                _DBPath = openDBDialog.FileName;
                Init();
            }
        }

    }
    public class DocumentCategorie
    {

        public DocumentCategorie()
        {
            _CSons = new List<DocumentCategorie>();
        }
        private int _CIndex;
        private string _CGuid;
        private string _CText;
        private string _CName;
        private DocumentCategorie _CParent;
        private string _CParentGuid;
        private string _RootGuid;
        private List<DocumentCategorie> _CSons;
        /// <summary>
        /// 添加子
        /// </summary>
        /// <param name="son"></param>
        public void AddSon(DocumentCategorie son)
        {
            _CSons.Add(son);
        }
        public List<DocumentCategorie> Sons
        {
            get { return _CSons; }
        }
        public string RootGuid
        {
            get { return _RootGuid; }
            set { _RootGuid = value; }
        }
        public bool HasSon
        {
            get
            {
                bool hasson = false; ;
                if (_CSons.Count > 0) { hasson = true; }
                return hasson;
            }
        }
        /// <summary>
        /// 排序
        /// </summary>
        public int Index
        {
            get { return _CIndex; }
            set { _CIndex = value; }
        }
        /// <summary>
        /// 标识
        /// </summary>
        public string Guid
        {
            get { return _CGuid; }
            set { _CGuid = value; }
        }
        /// <summary>
        /// 父标识
        /// </summary>
        public string ParentGuid
        {
            get { return _CParentGuid; }
            set { _CParentGuid = value; }
        }
        /// <summary>
        /// 显示的文本
        /// </summary>
        public string Text
        {
            get { return _CText; }
            set { _CText = value; }
        }
        /// <summary>
        /// 名称,英文
        /// </summary>
        public string Name
        {
            get { return _CName; }
            set { _CName = value; }
        }
        /// <summary>
        /// 父
        /// </summary>
        public DocumentCategorie Parent
        {
            get { return _CParent; }
            set { _CParent = value; }
        }
        public override string ToString()
        {
            return this.Text;
        }
    }
    public class DocumentCategorieTree
    {
        List<DocumentCategorie> DocumentCategorieList;

        public DocumentCategorieTree()
        {
            DocumentCategorieList = new List<DocumentCategorie>();
        }

        public void Add(DocumentCategorie documentcategorie)
        {
            foreach (DocumentCategorie categorie in DocumentCategorieList)
            {
                if (categorie.ParentGuid == documentcategorie.Guid)
                {
                    categorie.Parent = documentcategorie;
                    documentcategorie.AddSon(categorie);
                }
                if (documentcategorie.ParentGuid == categorie.Guid)
                {
                    documentcategorie.Parent = categorie;
                    categorie.AddSon(documentcategorie);
                }
            }
            DocumentCategorieList.Add(documentcategorie);
        }
        /// <summary>
        /// 返回根结点
        /// </summary>
        public List<DocumentCategorie> Root
        {

            get
            {
                List<DocumentCategorie> root = new List<DocumentCategorie>();
                foreach (DocumentCategorie categorie in DocumentCategorieList)
                {
                    if (string.IsNullOrEmpty(categorie.ParentGuid))
                    {
                        root.Add(categorie);
                    }
                }
                return root;
            }
        }
        public List<DocumentCategorie> Categories
        {
            get { return DocumentCategorieList; }
        }

    }
    public class DocumentInfo
    {
        public int Index;
        public string Guid;
        public string Title;
        public string Charset;
        public string KeyWords;
        public string Description;
        public string Remark;
        public string FileSavePath;
        public string FileName;
        public string Url;
        public string TemplateGuid;
        public DateTime AddTime;
        public DateTime AlterTime;
        public DateTime DeleteTime;
        public short Status;
        public string Content;
        private List<DocumentInfo> _DocumentInfoList = new List<DocumentInfo>();
        public List<DocumentInfo> DocumentInfoList
        {
            get { return _DocumentInfoList; }
        }
        public override string ToString()
        {
            string tostring = null;
            if (string.IsNullOrEmpty(this.KeyWords)) tostring = this.Title;
            else { tostring = this.KeyWords; }
            return tostring;
        }

    }
    public struct Document_DocumentCategories
    {
        public string DocumentGuid;
        public string CategorieGuid;
        public DocumentInfo Document;
    }
}